package com.ihr360.payroll.controller.spreadsheet.validator;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.ihr360.commons.context.session.Ihr360SessionContextHolder;
import com.ihr360.commons.entity.AuthUserInfo;
import com.ihr360.commons.lang.CollectionUtils;
import com.ihr360.commons.lang.StringUtils;
import com.ihr360.excel.specification.ColumnSpecification;
import com.ihr360.excel.specification.CommonSpecification;
import com.ihr360.excel.validation.SpreadSheetValidator;
import com.ihr360.excel.validation.annonation.SpreadSheetValid;
import com.ihr360.excel.vo.CustomSpreadSheetValidateResult;
import com.ihr360.excel.vo.SpreadSheetCell;
import com.ihr360.excel.vo.SpreadSheetRow;
import com.ihr360.excel.vo.SpreadSheetSpecification;
import com.ihr360.excel.vo.SpreadSheetValidatorRequest;
import com.ihr360.payroll.entity.staff.CompanySalaryProfileEntity;
import com.ihr360.payroll.entity.staff.SalaryProfileFieldEntity;
import com.ihr360.payroll.request.SalaryProfileFieldRequest;
import com.ihr360.payroll.request.SalaryProfileTypeItem;
import com.ihr360.payroll.request.StaffPayrollInfoRequest;
import com.ihr360.payroll.request.StaffPayrollInfosRequest;
import com.ihr360.payroll.service.salaryprofile.CompanySalaryProfileService;
import com.ihr360.payroll.service.staff.impl.StaffPayrollInfoServiceImpl;
import com.ihr360.payroll.service.staff.validator.StaffPayrollInfosValidator;
import com.ihr360.payroll.type.SalaryProfileChangeType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@SpreadSheetValid(code = "StaffSalary")
public class SalaryProfileImportValidator implements SpreadSheetValidator {


    @Autowired
    private CompanySalaryProfileService companySalaryProfileService;

    @Autowired
    private StaffPayrollInfosValidator staffPayrollInfosValidator;


    @Override
    public CustomSpreadSheetValidateResult customValidate(SpreadSheetValidatorRequest request) {
        CustomSpreadSheetValidateResult result = new CustomSpreadSheetValidateResult();
        List<SpreadSheetRow> spreadSheetRows = request.getSpreadSheetDatas();
        if (CollectionUtils.isEmpty(spreadSheetRows)) {
            return new CustomSpreadSheetValidateResult();
        }
        StaffPayrollInfosRequest staffPayrollInfosRequest = convertImportDataToRequestParam(spreadSheetRows);
        staffPayrollInfosValidator.validate(staffPayrollInfosRequest, result);
        return result;
    }

    private StaffPayrollInfosRequest convertImportDataToRequestParam(List<SpreadSheetRow> spreadSheetRows) {
        Map<String, List<SpreadSheetRow>> staffIdRowsMap = spreadSheetRows.stream().collect(Collectors.groupingBy(SpreadSheetRow::getStaffId));
        StaffPayrollInfosRequest staffPayrollInfosRequest = new StaffPayrollInfosRequest();
        List<StaffPayrollInfoRequest> payrollInfos = Lists.newArrayList();
        staffPayrollInfosRequest.setPayrollInfos(payrollInfos);

        AuthUserInfo authUserInfo = Ihr360SessionContextHolder.getSession().getUserInfo();
        CompanySalaryProfileEntity companySalaryProfileEntity = companySalaryProfileService.getByCompanyId(authUserInfo.getCompanyId());
        List<SalaryProfileFieldEntity> companyProfileFields = companySalaryProfileEntity.getProfileFields();
        Map<String, String> companyProfileFieldMap = Maps.newHashMap();

        if (CollectionUtils.isNotEmpty(companyProfileFields)) {
            companyProfileFieldMap = companyProfileFields.stream().collect(Collectors.toMap(SalaryProfileFieldEntity::getName, SalaryProfileFieldEntity::getCode));
        }

        Map<String, String> finalCompanyProfileFieldMap = companyProfileFieldMap;
        staffIdRowsMap.forEach((staffId, rows) -> {
            StaffPayrollInfoRequest payrollInfoRequest = new StaffPayrollInfoRequest();
            payrollInfos.add(payrollInfoRequest);

            payrollInfoRequest.setStaffId(staffId);
            payrollInfoRequest.setUserName(authUserInfo.getUserName());
            payrollInfoRequest.setUserId(authUserInfo.getUserId());
            List<SalaryProfileTypeItem> typeItems = Lists.newArrayList();
            payrollInfoRequest.setTypeItems(typeItems);
            String staffName = null;
            for (SpreadSheetRow row : rows) {
                SalaryProfileTypeItem item = new SalaryProfileTypeItem();
                typeItems.add(item);

                item.setRowNum(row.getRowNum());

                List<SalaryProfileFieldRequest> profileFields = Lists.newArrayList();
                item.setProfileFields(profileFields);
                List<SpreadSheetCell> cells = row.getCells();

                Date effectiveAt = null;
                SalaryProfileChangeType changeType = null;


                for (SpreadSheetCell cell : cells) {


                    if (StaffPayrollInfoServiceImpl.importConstant.get(StaffPayrollInfoServiceImpl.STAFF_SALARY_IMPORT_HEADER_KEY_NAME).equals(cell.getHeaderName())) {
                        staffName = String.valueOf(cell.getCellValue());
                        continue;
                    } else if (StaffPayrollInfoServiceImpl.importConstant.get(StaffPayrollInfoServiceImpl.STAFF_SALARY_IMPORT_HEADER_KEY_ADJUST_RESSON).equals(cell.getHeaderName())) {
                        changeType = SalaryProfileChangeType.getChangeType(String.valueOf(cell.getCellValue()));
                        continue;
                    } else if (StaffPayrollInfoServiceImpl.importConstant.get(StaffPayrollInfoServiceImpl.STAFF_SALARY_IMPORT_HEADER_KEY_EFFECTIVEAT).equals(cell.getHeaderName())) {
                        effectiveAt = new Date((Long) cell.getCellValue());
                        continue;
                    } else if (StaffPayrollInfoServiceImpl.importConstant.get(StaffPayrollInfoServiceImpl.STAFF_SALARY_IMPORT_HEADER_KEY_MOBILE).equals(cell.getHeaderName())) {
                        continue;
                    }else{
                        String code = finalCompanyProfileFieldMap.get(String.valueOf(cell.getHeaderName()));
                        if (StringUtils.isEmpty(code)) {
                            continue;
                        }
                    }

                    SalaryProfileFieldRequest salaryProfileFieldRequest = new SalaryProfileFieldRequest();
                    profileFields.add(salaryProfileFieldRequest);
                    salaryProfileFieldRequest.setAdjustManually(true);
                    salaryProfileFieldRequest.setName(cell.getHeaderName());
                    salaryProfileFieldRequest.setValue(String.valueOf(cell.getCellValue()));
                    salaryProfileFieldRequest.setCode(finalCompanyProfileFieldMap.get(String.valueOf(cell.getHeaderName())));
                    salaryProfileFieldRequest.setColNum(cell.getColNum());
                }
                item.setEffectiveAt(effectiveAt);
                item.setChangeType(changeType);
                for (SalaryProfileFieldRequest profileField : profileFields) {
                    profileField.setEffectiveAt(effectiveAt);
                    profileField.setChangeType(changeType);
                }
            }
            payrollInfoRequest.setStaffName(staffName);
        });

        return staffPayrollInfosRequest;

    }

    @Override
    public SpreadSheetSpecification commonSpecification(SpreadSheetValidatorRequest request) {
        SpreadSheetSpecification spreadSheetSpecification = new SpreadSheetSpecification();
        List<ColumnSpecification> columnSpecifications = new ArrayList<>();
        spreadSheetSpecification.setColumnSpecifications(columnSpecifications);
        CommonSpecification commonSpecification = CommonSpecification.createCommonSpecification(false);
        commonSpecification.setStaffNameAlias(Lists.newArrayList("姓名"));
        commonSpecification.setMobileNoAlias(Lists.newArrayList("手机号码", "手机号"));
        spreadSheetSpecification.setCommonSpecification(commonSpecification);


        ColumnSpecification notNullStringColumn = ColumnSpecification.createCellSpecification(String.class, false);
        ColumnSpecification notNullDateColumn = ColumnSpecification.createCellSpecification(Date.class, false);

        columnSpecifications.add(notNullStringColumn);
        columnSpecifications.add(notNullDateColumn);
        notNullStringColumn.addColumns("调整原因");
        notNullDateColumn.addColumns("生效日期");

        return spreadSheetSpecification;
    }
}
